//
//  InAppPurchase.m
//  PushInappTestiOS
//
//  Created by KyuJin on 13. 1. 1..
//
//

#import "InAppPurchase.h"
#import "AppManager.h"
#import "JSON.h"
#import "VerificationController.h"

static InAppPurchase *_instance;

@implementation InAppPurchase

+ (InAppPurchase*) getInstance
{
    if(!_instance){
        _instance = [[InAppPurchase alloc] init];
    }
    
    return _instance;
}

- (id) init
{
    self = [super init];
    m_PurchaseManager = [[EBPurchase alloc] init];
    m_PurchaseManager.delegate = self;
    
    return self;
}

- (void) dealloc
{
    [_instance release];
    _instance = nil;
    
    [m_PurchaseManager release];
    m_PurchaseManager = nil;
    
    [super dealloc];
}

#pragma mark - Purchase Function
- (void) requestProduct:(NSString*) itemID
{
    [m_PurchaseManager requestProduct:itemID];
}

- (void) purchaseProduct:(SKProduct*) product;
{
    
    if (product != nil)
    {
        // Then, call the purchase method.
        
        if (![m_PurchaseManager purchaseProduct:product])
        {
            // Returned NO, so notify user that In-App Purchase is Disabled in their Settings.
            NSLog(@"ViewController inAppPurchase is disable");
        }
    }
}

#pragma mark - EBPurchaseDelegate Methods
-(void) requestedProduct:(EBPurchase*)ebp identifier:(NSString*)productId name:(NSString*)productName price:(NSString*)productPrice description:(NSString*)productDescription
{
    NSLog(@"ViewController requestedProduct");
    
    if (productPrice != nil)
    {
        // Product is available, so update button title with price.
        
        //        [buyButton setTitle:[@"Buy Game Levels Pack " stringByAppendingString:productPrice] forState:UIControlStateNormal];
        //        buyButton.enabled = YES; // Enable buy button.
        
        [self purchaseProduct:ebp.validProduct];
    }
    else {
        // Product is NOT available in the App Store, so notify user.
        
        //        buyButton.enabled = NO; // Ensure buy button stays disabled.
        //        [buyButton setTitle:@"Buy Game Levels Pack" forState:UIControlStateNormal];
    }
}

-(void) successfulPurchase:(EBPurchase*)ebp restored:(bool)isRestore identifier:(NSString*)productId receipt:(SKPaymentTransaction*)transactionReceipt
{
    NSLog(@"ViewController successfulPurchase");
    
    // Purchase or Restore request was successful, so...
    // 1 - Unlock the purchased content for your new customer!
    // 2 - Notify the user that the transaction was successful.
    if(isRestore)
    {
        //Restored
    }
    else
    {
        [[VerificationController sharedInstance] verifyPurchase:transactionReceipt delegate:self];
        //Not Restored
    }
}

-(void) incompleteRestore:(EBPurchase*)ebp
{
    NSLog(@"InAppPurchase incompleteRestore");
}

-(void) failedPurchase:(EBPurchase*)ebp error:(NSInteger)errorCode message:(NSString*)errorMessage
{
    // Purchase or Restore request failed or was cancelled, so notify the user.
    NSLog(@"ViewController failedPurchase");
    
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    [dict setObject:@"inappfail" forKey:@"event"];
    [dict setObject:[NSString stringWithFormat:@"%d", errorCode] forKey:@"code"];
    [dict setObject:errorMessage forKey:@"message"];
    
    [[AppManager getInstance] sendJavascript:@"COMMON_Event" data:dict];
    [dict release];
}

-(void) failedRestore:(EBPurchase*)ebp error:(NSInteger)errorCode message:(NSString*)errorMessage
{
    // Restore request failed or was cancelled, so notify the user.
    NSLog(@"ViewController failedRestore");
    
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    [dict setObject:@"inappfail" forKey:@"event"];
    [dict setObject:[NSString stringWithFormat:@"%d", errorCode] forKey:@"code"];
    [dict setObject:errorMessage forKey:@"message"];
    
    [[AppManager getInstance] sendJavascript:@"COMMON_Event" data:dict];
    [dict release];
}

#pragma mark NSURLConnectionDelegate (for the verifyReceipt connection)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSString *responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
    
    // So we got some receipt data. Now does it all check out?
    BOOL isOk = [[VerificationController sharedInstance] doesTransactionInfoMatchReceipt:responseString];
    
    if (isOk)
    {
        //Validation suceeded. Unlock content here.
#warning Validation suceeded. Unlock content here.
        NSString *rawJSON;
        id jsonValue = nil;
        if ((rawJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]) != nil) {
            SBJsonParser *jsonParser = [[[SBJsonParser alloc] init] autorelease];
            if ((jsonValue = [jsonParser objectWithString:rawJSON]) == nil) {
                NSLog(@"This string doesn't seem to be JSON: '%@'\nraw Data : '%s'", rawJSON, nil);
            }
        }
        else {
            NSLog(@"This data doesn't seem to be an UTF8 encoded string: %@", data);
        }
        
        NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
        [dict setObject:@"inappsuccess" forKey:@"event"];
        [dict setObject:rawJSON forKey:@"result"];
        
        [[AppManager getInstance] sendJavascript:@"COMMON_Event" data:dict];
        
        NSDictionary *JSON =
        [NSJSONSerialization JSONObjectWithData: [rawJSON dataUsingEncoding:NSUTF8StringEncoding]
                                        options: NSJSONReadingMutableContainers
                                          error: nil];
        
        [dict release];
        [rawJSON release];
        NSLog(@"%@", JSON);
    }
}


- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        SecTrustRef trust = [[challenge protectionSpace] serverTrust];
        NSError *error = nil;
        BOOL didUseCredential = NO;
        BOOL isTrusted = [self validateTrust:trust error:&error];
        if (isTrusted)
        {
            NSURLCredential *trust_credential = [NSURLCredential credentialForTrust:trust];
            if (trust_credential)
            {
                [[challenge sender] useCredential:trust_credential forAuthenticationChallenge:challenge];
                didUseCredential = YES;
            }
        }
        if (!didUseCredential)
        {
            [[challenge sender] cancelAuthenticationChallenge:challenge];
        }
    } else {
        [[challenge sender] performDefaultHandlingForAuthenticationChallenge:challenge];
    }
}

// NOTE: These are needed for 4.x (as willSendRequestForAuthenticationChallenge: is not supported)
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust];
}


- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        SecTrustRef trust = [[challenge protectionSpace] serverTrust];
        NSError *error = nil;
        BOOL didUseCredential = NO;
        BOOL isTrusted = [self validateTrust:trust error:&error];
        if (isTrusted)
        {
            NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
            if (credential)
            {
                [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
                didUseCredential = YES;
            }
		}
        if (! didUseCredential) {
            [[challenge sender] cancelAuthenticationChallenge:challenge];
        }
    } else {
        [[challenge sender] performDefaultHandlingForAuthenticationChallenge:challenge];
    }
}


#pragma mark
#pragma mark NSURLConnection - Trust validation

- (BOOL)validateTrust:(SecTrustRef)trust error:(NSError **)error
{
    
    // Include some Security framework SPIs
    extern CFStringRef kSecTrustInfoExtendedValidationKey;
    extern CFDictionaryRef SecTrustCopyInfo(SecTrustRef trust);
    
    BOOL trusted = NO;
    SecTrustResultType trust_result;
    if ((noErr == SecTrustEvaluate(trust, &trust_result)) && (trust_result == kSecTrustResultUnspecified))
    {
        NSDictionary *trust_info = (__bridge_transfer NSDictionary *)SecTrustCopyInfo(trust);
        id hasEV = [trust_info objectForKey:(__bridge NSString *)kSecTrustInfoExtendedValidationKey];
        trusted =  [hasEV isKindOfClass:[NSValue class]] && [hasEV boolValue];
    }
    
    if (trust)
    {
        if (!trusted && error)
        {
            *error = [NSError errorWithDomain:@"kSecTrustError" code:(NSInteger)trust_result userInfo:nil];
        }
        return trusted;
    }
    return NO;
}
@end
